//
// Created by blackplume on 17-10-19.
//

#include "Buildin_Command.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "Command.h"



in_Command::in_Command(char *name, int (*fun)( char **, char *&) ) {

    this->func=fun;
    this->name=name;
    this->fmode=0;
}

in_Command::in_Command(char *name, int (*fun)( char **, char *&),int mode ) {

    this->func=fun;
    this->name=name;
    this->fmode=mode;
}

void Init(){
    in_command=(in_Command**)malloc(sizeof(in_Command*)*(IN_COMMAND_NUM+1));
    in_command[0]=new in_Command("cd",cd_command,NO_FORK);
    //No fork的内建命令不接收重定向；
    in_command[1]=new in_Command("quit",quit_comand,NO_FORK);
    in_command[2]=new in_Command("about",about_comand);
#ifdef DEBUG
    in_command[3]=new in_Command("testin",testIn_command);
#endif
}

int GetIndex(const char* name){
    for(int i=0;i<IN_COMMAND_NUM;i++){
        if(in_command[1]!=NULL&&strcmp(name,in_command[i]->name)==0){
            return i;
        }
    }
    return -1;
}

int isFork(int i){
    return  in_command[i]->fmode;
}

void run(int index, char** parameters, char*&out){
    in_command[index]->func(parameters,out);
}

// 1:>> 2:> 3:<< 4:<
int Redirection(read_info * info,char* path){
    int fd;
    if(info->IsRedirect==1){
        fd=open(path,O_RDWR|O_CREAT|O_APPEND,0644);
        dup2(fd,1);
        close(fd);
        return 1;
    }
    if(info->IsRedirect==2){
        fd=open(path,O_RDWR|O_CREAT,0644);
        dup2(fd,1);
        close(fd);
        return 1;
    }
    if(info->IsRedirect==4){
        fd=open(path,O_RDWR|O_CREAT,0644);
        dup2(fd,0);
        close(fd);
        return 1;
    }

    return 0;
}

int repipe(){
    int num=0;
    int i=0;
    char * test=(char*)malloc(sizeof(char)*100);
    while((i=read(STDIN_FILENO,test,99))!=0){
        //num+=i;
        printf("1");
        //printf("%s::asdfsdf",test);
        //printf("%d",&i);
    }
    printf("aaaa");
    return num;
}

int DoCommand(read_info* info,char* command,char ** parameters,char *&out){

    if(info->Redirect2!=NULL){
        Redirection(info,info->Redirect2);
    }
    if(info->IsBuildin2){
        run(info->index2,parameters,out);
        return 0;
    } else{
        if(info->IsPath2== false){
            if(execvp(command,parameters)==-1){
                printf("%s is not exist\n",&command);
                repipe();
                return -1;
            }
        }/* execute command */
        else{
            if(execv(info->Path2,parameters)==-1){
                printf("%s is not exist\n",&command);
                repipe();
                return -1;
            }
        }
    }
}